package elevation

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strconv"
)

// ElevationResponse represents the JSON response structure
type ElevationResponse struct {
	Code    int     `json:"code"`
	Data    float64 `json:"data"`
	Message string  `json:"message"`
}

// Handler handles HTTP requests for elevation data
type Handler struct {
	GeoTIFF *GeoTIFF
}

// NewHandler creates a new elevation handler
func NewHandler(geoTiff *GeoTIFF) *Handler {
	return &Handler{
		GeoTIFF: geoTiff,
	}
}

// GetElevationHandler handles GET requests to /elevation
func (h *Handler) GetElevationHandler(w http.ResponseWriter, r *http.Request) {
	// Set content type
	w.Header().Set("Content-Type", "application/json")

	// Parse query parameters
	latStr := r.URL.Query().Get("lat")
	lonStr := r.URL.Query().Get("lon")

	log.Printf("Received request for lat=%s, lon=%s", latStr, lonStr)

	if latStr == "" || lonStr == "" {
		log.Printf("Missing lat or lon parameter")

		// Create error response
		response := ElevationResponse{
			Code:    400,
			Data:    0,
			Message: "缺少经纬度参数",
		}

		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(response)
		return
	}

	// Convert to float64
	lat, err := strconv.ParseFloat(latStr, 64)
	if err != nil {
		log.Printf("Invalid lat parameter: %v", err)

		// Create error response
		response := ElevationResponse{
			Code:    400,
			Data:    0,
			Message: "无效的纬度参数",
		}

		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(response)
		return
	}

	lon, err := strconv.ParseFloat(lonStr, 64)
	if err != nil {
		log.Printf("Invalid lon parameter: %v", err)

		// Create error response
		response := ElevationResponse{
			Code:    400,
			Data:    0,
			Message: "无效的经度参数",
		}

		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(response)
		return
	}

	log.Printf("Parsed coordinates: lat=%f, lon=%f", lat, lon)

	// Convert lat/lon to pixel coordinates
	x, y, err := h.GeoTIFF.LatLonToPixel(lat, lon)
	if err != nil {
		log.Printf("Failed to convert coordinates: %v", err)

		// Create error response
		response := ElevationResponse{
			Code:    500,
			Data:    0,
			Message: fmt.Sprintf("坐标转换失败: %v", err),
		}

		w.WriteHeader(http.StatusInternalServerError)
		json.NewEncoder(w).Encode(response)
		return
	}

	log.Printf("Pixel coordinates: x=%f, y=%f", x, y)
	log.Printf("Image dimensions: %dx%d", h.GeoTIFF.Width, h.GeoTIFF.Height)

	// Check bounds before getting elevation
	if x < 0 || y < 0 || x >= float64(h.GeoTIFF.Width) || y >= float64(h.GeoTIFF.Height) {
		log.Printf("Coordinates out of bounds: x=%f, y=%f, image size=%dx%d", x, y, h.GeoTIFF.Width, h.GeoTIFF.Height)

		// Create error response
		response := ElevationResponse{
			Code:    400,
			Data:    0,
			Message: "坐标超出范围",
		}

		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(response)
		return
	}

	// Get elevation value
	elevation, err := h.GeoTIFF.GetElevation(x, y)
	if err != nil {
		log.Printf("Failed to get elevation: %v", err)

		// Create error response
		response := ElevationResponse{
			Code:    400,
			Data:    0,
			Message: fmt.Sprintf("获取高程失败: %v", err),
		}

		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(response)
		return
	}

	log.Printf("Elevation value: %f", elevation)

	// Create success response
	response := ElevationResponse{
		Code:    200,
		Data:    elevation,
		Message: "高度获取成功",
	}

	// Encode and send response
	if err := json.NewEncoder(w).Encode(response); err != nil {
		log.Printf("Failed to encode response: %v", err)
		http.Error(w, "Failed to encode response", http.StatusInternalServerError)
		return
	}
}
